<template>
  <div class="box">
    <transition name="fade">
      <p v-if="displayText" class="footer" :class="{ animated: animating }">{{ displayText }}</p>
    </transition>
  </div>
</template>

<script setup lang="ts">
import axios from "axios";
import { ref, onMounted, onUnmounted } from "vue";

const displayText = ref("");
const animating = ref(false);
const text = ref("");
let timer = ref();
let requestSource: any = null;

const reqText = async () => {
  try {
    text.value = "";
    displayText.value = "";

    // 取消之前的请求
    if (requestSource) {
      requestSource.cancel();
    }

    // 创建新的取消令牌
    requestSource = axios.CancelToken.source();

    const response = await axios.get("https://v1.hitokoto.cn", {
      cancelToken: requestSource.token
    });
    const data = response.data;
    text.value = data.hitokoto + " ----《" + data.from + "》";
    showText();
  } catch (error) {
    if (!axios.isCancel(error)) {
      // 只处理非取消的错误
      console.error(error);
    }
  }
};

const showText = () => {
  if (timer.value) {
    clearInterval(timer.value);
    timer.value = null;
  }

  animating.value = true;
  const textArray = text.value.split("");
  let currentIndex = 0;

  timer.value = setInterval(() => {
    displayText.value += textArray[currentIndex];
    currentIndex++;

    if (currentIndex === textArray.length) {
      clearInterval(timer.value);
      animating.value = false;
      timer.value = setTimeout(() => {
        reqText();
      }, 300000);
    }
  }, 200);
};

onMounted(() => {
  reqText();
});

onUnmounted(() => {
  if (timer.value) {
    clearInterval(timer.value);
  }

  if (requestSource) {
    requestSource.cancel();
  }
});
</script>

<style lang="scss" scoped>
.box {
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}

.fade-enter,
.fade-leave-to {
  opacity: 0;
}

.animated {
  animation: fadeIn 0.5s;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.footer {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>